﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace LowLevelGraphics.Extractors
{
    /// <summary>
    /// For example
    /// 
    /// we have an image at level n
    /// n + 1 = downSample(n)
    /// diff n = upSampler(n + 1)
    /// diff n = differencer(n, n') - This diff n is saved for each level
    /// Later we want to get n from n+1
    /// n' = upSampler(n + 1)
    /// n = combiner(n', diff n)
    /// </summary>
    public class ImagePyramid : IExtractor
    {
        protected UnsafeBitmap m_Bitmap = null;
        protected IImagePyramidSampler m_Downsampler = null;
        protected IImagePyramidSampler m_UpSampler = null;
        protected IImagePyramidRenderOperations m_Differencer = null;
        protected IImagePyramidRenderOperations m_Combiner = null;

        protected List<UnsafeBitmap> m_aBitmap = new List<UnsafeBitmap>();

        protected UnsafeBitmap m_DifferencerImage = null;
        protected UnsafeBitmap m_UpImage = null;
        protected UnsafeBitmap m_DownImage = null;
        protected UnsafeBitmap m_CombinerImage = null;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_bitmap"></param>
        public ImagePyramid(UnsafeBitmap _bitmap)
        {
            m_Downsampler = new DefaultSizeSampler(_bitmap, 0.5f, 0.5f);
            m_UpSampler = new DefaultSizeSampler(_bitmap, 2.0f, 2.0f);
            m_Differencer = new DefaultDifferencer();
            m_Combiner = new DefaultCombiner();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="_bitmap"></param>
        public ImagePyramid(UnsafeBitmap _bitmap, IImagePyramidSampler _downSampler, IImagePyramidSampler _upSampler, IImagePyramidRenderOperations _differencer, IImagePyramidRenderOperations _combiner)
        {
            m_Bitmap = _bitmap;
            m_Downsampler = _downSampler;
            m_UpSampler = _upSampler;
            m_Differencer = _differencer;
            m_Combiner = _combiner;
        }

        /// <summary>
        /// 
        /// </summary>
        public virtual void Execute()
        {
            m_DownImage = m_Downsampler.Execute();
            this.m_aBitmap.Add(m_DownImage);

            m_UpImage = m_UpSampler.Execute();
            this.m_aBitmap.Add(m_UpImage);

            m_DifferencerImage = m_Differencer.Execute(m_DownImage, m_UpImage);
            m_CombinerImage = m_Combiner.Execute(m_UpImage, m_DownImage);
        }

        /// <summary>
        /// Gets bitmap...
        /// </summary>
        /// <param name="_nIndex"></param>
        /// <returns></returns>
        public UnsafeBitmap this[int _nIndex]
        {
            get { return m_aBitmap[_nIndex]; }
        }

        /// <summary>
        /// 
        /// </summary>
        public UnsafeBitmap CurrentImage
        {
            get { return null; }
        }

        /// <summary>
        /// 
        /// </summary>
        public UnsafeBitmap DiffImage
        {
            get { return m_DifferencerImage; }
        }

        public UnsafeBitmap CombinerImage
        {
            get { return m_CombinerImage; }
        }

        public UnsafeBitmap UpSampledImage
        {
            get { return m_UpImage; }
        }

        public UnsafeBitmap DownSampledImage
        {
            get { return m_DownImage; }
        }
    }
}
